﻿using GalaSoft.MvvmLight;
using BaffoHat.Core;
using System.Collections.ObjectModel;
using GalaSoft.MvvmLight.Command;
using System.Collections.Generic;
using BaffoHat.Wpf.Controls;

namespace BaffoHat.Wpf.ViewModel
{
    public class MainViewModel : ViewModel
    {
        #region Property      

        private Game game;

        private ObservableCollection<Player> players;

        public ObservableCollection<Player> Players
        {
            get { return players; }
            set 
            { 
                players = value;
                OnPropertyChanged<ObservableCollection<Player>>(() => this.Players);
            }
        }

        private Player selectedPlayer;

        public Player SelectedPlayer
        {
            get { return selectedPlayer; }
            set
            {
                selectedPlayer = value;
                OnPropertyChanged<Player>(() => this.SelectedPlayer);
            }
        }

        private string playerName;

        public string PlayerName
        {
            get { return playerName; }
            set 
            {
                playerName = value; 
                OnPropertyChanged<string>(() => this.PlayerName);
            }
        }

        private ObservableCollection<Glass> glasses;

        public ObservableCollection<Glass> Glasses
        {
            get { return glasses; }
            set 
            { 
                glasses = value;
                OnPropertyChanged<ObservableCollection<Glass>>(() => this.Glasses);
            }
        }

        private DiceFace? diceFace;

        public DiceFace? DiceFace
        {
            get { return diceFace; }
            set
            {
                diceFace = value;
                OnPropertyChanged<DiceFace?>(() => this.DiceFace);
            }
        }

        public GameStatus Status
        {
            get { return game.Status; }
        }

        #endregion

        #region Costructor
        /// <summary>
        /// Initializes a new instance of the MainViewModel class.
        /// </summary>
        public MainViewModel()
        {
            game = new Game();
            Players = new ObservableCollection<Player>(game.Players);

            this.AddPlayerCommand = new RelayCommand(OnAddPlayer, () => CanAddPlayer);
            this.StartGameCommand = new RelayCommand(OnStartGame, () => CanStartGame);
            this.RollDiceCommand = new RelayCommand(OnRollDice, () => CanRollDice);
            this.DrinkCommand = new RelayCommand(OnDrink, () => CanDrink);

            if (IsInDesignMode)
            {
                // Code runs in Blend --> create design time data.
            }
            else
            {
                // Code runs "for real"
            }
        }
        #endregion

        public RelayCommand AddPlayerCommand { get; set; }

        private void OnAddPlayer()
        {
            Player player = new Player(PlayerName);
            game.AddPlayer(player);
            Players.Add(player);
            PlayerName = "";
        }

        public bool CanAddPlayer
        {
            get
            {
                if(Status == GameStatus.PlayersConfiguration && !string.IsNullOrEmpty( PlayerName))
                    return true;
                return false;
            }
        }

        public RelayCommand StartGameCommand { get; set; }

        private void OnStartGame()
        {
            game.StartGame();
            //TODO si può fare meglio
            //Quando tira il dado deve aggiornarsi lo stato dei bicchieri
            UpdateGlasses();
            UpdatePlayers();
        }

        public bool CanStartGame
        {
            get
            {
                if (Status == GameStatus.PlayersConfiguration && Players.Count > 0)
                    return true;
                return false;
            }
        }

        public RelayCommand RollDiceCommand { get; set; }

        private void OnRollDice()
        {
            DiceFace = game.RollDice();

            //TODO si può fare meglio
            //Quando tira il dado deve aggiornarsi lo stato dei bicchieri
            UpdateGlasses();

            SelectedPlayer = game.PlayerTurn;
        }

        public bool CanRollDice
        {
            get
            {
                if (Status == GameStatus.WaitingDieRoll)
                    return true;
                return false;
            }
        }

        public RelayCommand DrinkCommand { get; set; }

        private void OnDrink()
        {
            game.Drink();
            DiceFace = null;
            //TODO si può fare meglio
            //Quando bevo deve aggiornarsi lo stato del giocatore
            UpdatePlayers();
            UpdateGlasses();
        }

        public bool CanDrink
        {
            get
            {
                if (Status == GameStatus.WaitingDrinks)
                    return true;
                return false;
            }
        }

        private void UpdateGlasses()
        {
            Glasses = new ObservableCollection<Glass> { 
                game.Glasses.One,
                game.Glasses.Two,
                game.Glasses.Three,
                game.Glasses.Four,
                game.Glasses.Five,
                game.Glasses.Six};
        }

        private void UpdatePlayers()
        {
            Players = new ObservableCollection<Player>(game.Players);
            SelectedPlayer = game.PlayerTurn;
        }

        public override void Cleanup()
        {
            base.Cleanup();
            KinectSensor.Instance.Uninitialize();
        }
    }
}